Node.js Logging

Node.js பயன்பாடுகளில் பதிவு மேலாண்மை மற்றும் கண்காணிப்பு தொழில்நுட்பங்களைக் கற்றுக்கொள்ளுங்கள்

பதிவு ஏன் முக்கியமானது

பயனுள்ள பதிவு பல காரணங்களுக்கு அவசியம்:

பிழைத்திருத்தம்

உங்கள் பயன்பாட்டிற்குள் என்ன நடக்கிறது என்பதைப் புரிந்துகொள்ளவும்

சிக்கல் தீர்த்தல்

உற்பத்தி சூழல்களில் சிக்கல்களைக் கண்டறியவும்

கண்காணிப்பு

பயன்பாட்டு ஆரோக்கியம் மற்றும் செயல்திறனைக் கண்காணிக்கவும்

தணிக்கை

இணக்கமும் பாதுகாப்பும் குறித்த முக்கிய நிகழ்வுகளைப் பதிவுசெய்யவும்

பகுப்பாய்வு

பயன்பாட்டு பயன்பாடு மற்றும் நடத்தை பற்றிய தரவைச் சேகரிக்கவும்

கன்சோல் மூலம் அடிப்படை பதிவு

Node.js அடிப்படை பதிவுக்காக உள்ளமைக்கப்பட்ட கன்சோல் முறைகளை வழங்குகிறது:

// Basic logging
console.log('Info message');
console.error('Error message');
console.warn('Warning message');
console.debug('Debug message');

// Log objects
const user = { id: 1, name: 'John', roles: ['admin', 'user'] };
console.log('User object:', user);

// Table output for arrays or objects
console.table([
  { name: 'John', age: 30, role: 'admin' },
  { name: 'Jane', age: 25, role: 'user' },
  { name: 'Bob', age: 40, role: 'guest' }
]);

// Timing operations
console.time('operation');
// Perform some operations...
for (let i = 0; i < 1000000; i++) {
  // Do something
}
console.timeEnd('operation'); // Outputs: operation: 4.269ms

// Grouping related logs
console.group('User Processing');
console.log('Loading user data...');
console.log('Validating user...');
console.log('Updating user profile...');
console.groupEnd();

// Stack trace
console.trace('Trace message');

கன்சோல் வரம்புகள்

கன்சோல் வசதியானது என்றாலும், உற்பத்தி பயன்பாட்டிற்கு குறிப்பிடத்தக்க வரம்புகளைக் கொண்டுள்ளது:

வடிகட்டுதலுக்கு உள்ளமைக்கப்பட்ட பதிவு நிலைகள் இல்லை
பதிவு சுழற்சி அல்லது கோப்பு மேலாண்மை இல்லை
JSON போன்ற கட்டமைக்கப்பட்ட வெளியீட்டு வடிவங்கள் இல்லை
கண்காணிப்பு அமைப்புகளுடன் வரையறுக்கப்பட்ட ஒருங்கிணைப்பு

⚠️ குறிப்பு:

கன்சோல் முறைகள் டெர்மினல்கள்/கோப்புகளுக்கு வெளியீடு செய்யும் போது ஒத்திசைவாக இருக்கும் மற்றும் உற்பத்தியில் அடிக்கடி பயன்படுத்தப்பட்டால் செயல்திறனை பாதிக்கும்.

கட்டமைக்கப்பட்ட பதிவு

கட்டமைக்கப்பட்ட பதிவு வடிவங்கள் ப்ளெயின் உரைக்கு பதிலாக தரவு பொருள்களாக (பொதுவாக JSON) பதிவு செய்திகளை வடிவமைக்கின்றன, அவற்றை பாகுபடுத்த, தேட மற்றும் பகுப்பாய்வு செய்வதை எளிதாக்குகின்றன.

கட்டமைக்கப்பட்ட பதிவின் நன்மைகள்

இயந்திர வாசிப்புக்கான சீரான வடிவம்
சிறந்த தேடல் மற்றும் வடிகட்டுதல் திறன்
பதிவு ஒருங்கிணைப்பு கருவிகளுடன் எளிமைப்படுத்தப்பட்ட ஒருங்கிணைப்பு
மெட்டாடேட்டாவுடன் மேம்பட்ட சூழல்

கட்டமைக்கப்பட்ட பதிவு உள்ளீட்டின் எடுத்துக்காட்டு (JSON)

{
  "timestamp": "2023-11-28T15:24:39.123Z",
  "level": "error",
  "message": "Failed to connect to database",
  "service": "user-service",
  "context": {
    "requestId": "req-123-456",
    "userId": "user-789",
    "databaseHost": "db.example.com"
  },
  "error": {
    "name": "ConnectionError",
    "message": "Connection refused",
    "stack": "..."
  }
}

பிரபலமான Node.js பதிவு நூலகங்கள்

Winston

Winston என்பது பல போக்குவரத்துகளுக்கு (வெளியீடுகள்) ஆதரவுடன் ஒரு பல்துறை பதிவு நூலகமாகும்:

அடிப்படை Winston அமைப்பு

const winston = require('winston');

// Create a logger
const logger = winston.createLogger({
  level: 'info',
  format: winston.format.json(),
  defaultMeta: { service: 'user-service' },
  transports: [
    // Write logs to a file
    new winston.transports.File({ filename: 'error.log', level: 'error' }),
    new winston.transports.File({ filename: 'combined.log' }),
  ],
});

// If not in production, also log to the console
if (process.env.NODE_ENV !== 'production') {
  logger.add(new winston.transports.Console({
    format: winston.format.simple(),
  }));
}

// Usage
logger.log('info', 'Hello distributed log files!');
logger.info('Hello again distributed logs');
logger.error('Something went wrong', { additionalInfo: 'error details' });

தனிப்பயன் Winston வடிவங்கள்

const winston = require('winston');
const { format } = winston;
const { combine, timestamp, label, printf } = format;

// Custom format
const myFormat = printf(({ level, message, label, timestamp }) => {
  return `${timestamp} [${label}] ${level}: ${message}`;
});

const logger = winston.createLogger({
  format: combine(
    label({ label: 'API Service' }),
    timestamp(),
    myFormat
  ),
  transports: [
    new winston.transports.Console(),
    new winston.transports.File({ filename: 'combined.log' })
  ]
});

logger.info('Application started');

Pino

Pino என்பது உகந்த செயல்திறனுடன் குறைந்த மேலோட்ட பதிவாக்கியாக வடிவமைக்கப்பட்டுள்ளது:

அடிப்படை Pino அமைப்பு

const pino = require('pino');

// Create a logger
const logger = pino({
  level: 'info',
  timestamp: pino.stdTimeFunctions.isoTime,
  base: { pid: process.pid, hostname: require('os').hostname() }
});

// Usage
logger.info('Application started');
logger.info({ user: 'john' }, 'User logged in');
logger.error({ err: new Error('Connection failed') }, 'Database connection error');

Express உடன் Pino

const express = require('express');
const pino = require('pino');
const pinoHttp = require('pino-http');

const app = express();
const logger = pino();
const httpLogger = pinoHttp({ logger });

// Add request logging middleware
app.use(httpLogger);

app.get('/', (req, res) => {
  req.log.info('User accessed homepage');
  res.send('Hello World!');
});

app.get('/error', (req, res) => {
  req.log.error('Something went wrong');
  res.status(500).send('Error!');
});

app.listen(8080, () => {
  logger.info('Server started on port 8080');
});

Bunyan

Bunyan என்பது பதிவுகளைக் காண CLI உடன் கூடிய கட்டமைக்கப்பட்ட பதிவு நூலகமாகும்:

அடிப்படை Bunyan அமைப்பு

const bunyan = require('bunyan');

// Create a logger
const logger = bunyan.createLogger({
  name: 'myapp',
  streams: [
    {
      level: 'info',
      stream: process.stdout
    },
    {
      level: 'error',
      path: 'error.log'
    }
  ],
  serializers: bunyan.stdSerializers
});

// Usage
logger.info('Application started');
logger.info({ user: 'john' }, 'User logged in');
logger.error({ err: new Error('Connection failed') }, 'Database connection error');

பயன்பாட்டு பதிவு சிறந்த நடைமுறைகள்

பதிவு நிலைகள்

பதிவு செய்திகளின் முக்கியத்துவம் மற்றும் அவசரத்தை வகைப்படுத்த பொருத்தமான பதிவு நிலைகளைப் பயன்படுத்தவும்:

நிலை விளக்கம்
error இயக்கநேர பிழைகள், விதிவிலக்குகள் மற்றும் கவனம் தேவைப்படும் தோல்விகள்
warn பயன்பாட்டை நிறுத்தாத ஆனால் சாத்தியமான சிக்கல்களைக் குறிக்கும் எச்சரிக்கை நிலைமைகள்
info பயன்பாட்டு நிகழ்வுகள் மற்றும் மைல்கற்கள் பற்றிய தகவல் செய்திகள்
debug வளர்ச்சியின் போது பயனுள்ள விரிவான கண்டறியும் தகவல்
trace மிகவும் விரிவான பிழைத்திருத்த தகவல் (முறை நுழைவு/வெளியேற்றம், மாறி மதிப்புகள்)

என்ன பதிவு செய்வது

பதிவு செய்ய வேண்டியவை:

  • பயன்பாட்டு தொடக்கம்/நிறுத்தம் நிகழ்வுகள்
  • அங்கீகாரம் மற்றும் அங்கீகார நிகழ்வுகள்
  • API கோரிக்கைகள் மற்றும் பதில்கள்
  • தரவுத்தள செயல்பாடுகள் மற்றும் செயல்திறன் அளவீடுகள்
  • சூழலுடன் கூடிய பிழைகள் மற்றும் விதிவிலக்குகள்
  • வள பயன்பாடு மற்றும் செயல்திறன் அளவீடுகள்
  • கட்டமைப்பு மாற்றங்கள்

பதிவு செய்ய வேண்டாம்:

  • கடவுச்சொற்கள், டோக்கன்கள், API விசைகள் அல்லது பிற சான்றுகள்
  • சரியான பாதுகாப்பு இல்லாமல் தனிப்பட்ட அடையாளம் காணக்கூடிய தகவல் (PII)
  • கிரெடிட் கார்டு எண்கள், சமூக பாதுகாப்பு எண்கள் அல்லது பிற உணர்திறன் தரவு
  • அமர்வு IDகள் அல்லது குக்கீகள்
  • குறியாக்க விசைகள்

சூழல் பதிவு

சிக்கல் தீர்த்தலை எளிதாக்குவதற்காக ஒவ்வொரு பதிவு உள்ளீட்டிலும் தொடர்புடைய சூழலைச் சேர்க்கவும்:

const winston = require('winston');

// Create a base logger
const logger = winston.createLogger({
  level: 'info',
  format: winston.format.json(),
  transports: [new winston.transports.Console()]
});

// Create a child logger with request context
function createRequestLogger(req) {
  return logger.child({
    requestId: req.id,
    method: req.method,
    url: req.url,
    ip: req.ip,
    userId: req.user ? req.user.id : 'anonymous'
  });
}

// Usage in Express middleware
app.use((req, res, next) => {
  req.id = generateRequestId();
  req.logger = createRequestLogger(req);
  req.logger.info('Request received');

  const start = Date.now();

  res.on('finish', () => {
    const duration = Date.now() - start;
    req.logger.info({
      statusCode: res.statusCode,
      duration: duration
    }, 'Request completed');
  });

  next();
});

function generateRequestId() {
  return Date.now().toString(36) + Math.random().toString(36).substring(2);
}

பதிவு மேலாண்மை மற்றும் பகுப்பாய்வு

பதிவு சுழற்சி

பதிவு சுழற்சியை செயல்படுத்துவதன் மூலம் பதிவு கோப்புகள் மிகவும் பெரிதாக வளர்வதைத் தடுக்கவும்:

சுழலும் கோப்பு போக்குவரத்துடன் Winston

const winston = require('winston');
require('winston-daily-rotate-file');

const transport = new winston.transports.DailyRotateFile({
  filename: 'application-%DATE%.log',
  datePattern: 'YYYY-MM-DD',
  zippedArchive: true,
  maxSize: '20m',
  maxFiles: '14d'
});

const logger = winston.createLogger({
  level: 'info',
  format: winston.format.json(),
  transports: [
    transport,
    new winston.transports.Console()// Optional console transport
  ]
});

logger.info('Hello rotated logs');

மையப்படுத்தப்பட்ட பதிவு

பல சேவையகங்கள் அல்லது கொள்கலன்களில் இயங்கும் பயன்பாடுகளுக்கு, உங்கள் பதிவுகளை எளிதான பகுப்பாய்வுக்காக மையப்படுத்தவும்:

Elasticsearch போக்குவரத்துடன் Winston

const winston = require('winston');
require('winston-elasticsearch');

const esTransportOpts = {
  level: 'info',
  clientOpts: {
    node: 'http://localhost:9200'
  },
  indexPrefix: 'app-logs'
};

const logger = winston.createLogger({
  transports: [
    new winston.transports.Elasticsearch(esTransportOpts),
    new winston.transports.Console()// Optional console transport
  ]
});

logger.info('This log will go to Elasticsearch');

பிரபலமான பதிவு மேலாண்மை அமைப்புகள்

ELK Stack (Elasticsearch, Logstash, Kibana): விரிவான பதிவு ஸ்டாக்
Graylog: பாதுகாப்பில் கவனம் செலுத்தும் மையப்படுத்தப்பட்ட பதிவு மேலாண்மை
Fluentd/Fluent Bit: பதிவு சேகரிப்பு மற்றும் அனுப்புதல்
Loki: இலகுவான பதிவு ஒருங்கிணைப்பு அமைப்பு
வணிக விருப்பங்கள்: Datadog, New Relic, Splunk, LogDNA, Loggly

உற்பத்தியில் பதிவு

செயல்திறன் பரிசீலனைகள்

இவெண்ட் லூப்பைத் தடுக்காமல் இருக்க அசிங்க்ரோனஸ் பதிவைப் பயன்படுத்தவும்
சிறந்த செயல்திறனுக்காக பதிவுகளை பஃப்பர் செய்யவும்
உற்பத்தியில் அளவைக் குறைக்க பதிவு நிலைகளை சரிசெய்யவும்
ஒவ்வொரு நிகழ்வையும் பதிவு செய்வதற்குப் பதிலாக உயர்-அளவிலான பதிவுகளை மாதிரி எடுக்கவும்

பாதுகாப்பு பரிசீலனைகள்

பதிவு செய்வதற்கு முன் உணர்திறன் தரவைத் தூய்மைப்படுத்தவும்
பொருத்தமான அனுமதிகளுடன் பதிவு கோப்புகளைப் பாதுகாக்கவும்
பதிவுகளை அனுப்பும் போது குறியாக்கத்தைப் பயன்படுத்தவும்
பதிவு தரவுக்கான தக்கவைப்புக் கொள்கைகளைச் செயல்படுத்தவும்
தொடர்புடைய ஒழுங்குமுறைகளுடன் (GDPR, HIPAA, முதலியன) இணக்கம் உள்ளதா என சரிபார்க்கவும்

தரவு தூய்மைப்படுத்தல் எடுத்துக்காட்டு

const winston = require('winston');

// Custom format to sanitize sensitive data
const sanitizeFormat = winston.format((info) => {
  if (info.user && info.user.password) {
    info.user.password = '[REDACTED]';
  }

  if (info.user && info.user.creditCard) {
    info.user.creditCard = '[REDACTED]';
  }

  if (info.headers && info.headers.authorization) {
    info.headers.authorization = '[REDACTED]';
  }

  return info;
});

const logger = winston.createLogger({
  format: winston.format.combine(
    sanitizeFormat(),
    winston.format.json()
  ),
  transports: [
    new winston.transports.Console()
  ]
});

// This sensitive data will be sanitized in the logs
logger.info({
  message: 'User registered',
  user: {
    name: 'John',
    email: 'john@example.com',
    password: 'secret123',
    creditCard: '4111-1111-1111-1111'
  },
  headers: {
    authorization: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
  }
});

பதிவுகளுடன் பிழைத்திருத்தம்

Debug தொகுதி

debug தொகுதி நிபந்தனை பிழைத்திருத்த பதிவைச் சேர்க்க ஒரு இலகுவான வழியை வழங்குகிறது:

const debug = require('debug');

// Create named debuggers
const dbDebug = debug('app:db');
const apiDebug = debug('app:api');
const authDebug = debug('app:auth');

// Usage
dbDebug('Connected to database');
apiDebug('API request received at /users');
authDebug('User authenticated: %o', { id: 123, roles: ['admin'] });

// Enable with environment variable:
// DEBUG=app:* node app.js
// or
// DEBUG=app:db,app:auth node app.js

தொடர்பு IDகள்

தொடர்பு IDகளைப் பயன்படுத்தி பல சேவைகளில் கோரிக்கைகளைக் கண்காணிக்கவும்:

const express = require('express');
const { v4: uuidv4 } = require('uuid');
const winston = require('winston');
const app = express();

// Create a logger
const logger = winston.createLogger({
  transports: [new winston.transports.Console()],
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.json()
  )
});

// Correlation ID middleware
app.use((req, res, next) => {
  // Extract correlation ID from the request header or generate a new one
  const correlationId = req.headers['x-correlation-id'] || uuidv4();

  // Add it to the response headers
  res.setHeader('x-correlation-id', correlationId);

  // Add it to the request object
  req.correlationId = correlationId;

  // Create a request-specific logger
  req.logger = logger.child({ correlationId });

  req.logger.info({
    message: 'Request received',
    method: req.method,
    url: req.url
  });

  next();
});

// Routes
app.get('/', (req, res) => {
  req.logger.info('Processing home request');
  res.send('Hello World');
});

app.get('/error', (req, res) => {
  req.logger.error('Error occurred in request');
  res.status(500).send('Error');
});

app.listen(8080, () => {
  logger.info('Server started on port 8080');
});

சுருக்கம்

பயனுள்ள பதிவு Node.js பயன்பாடுகளை பிழைத்திருத்தம், கண்காணிப்பு மற்றும் சிக்கல் தீர்த்தலுக்கு முக்கியமானது
சிறந்த தேடல் திறன் மற்றும் பகுப்பாய்வுக்காக JSON வடிவத்துடன் கட்டமைக்கப்பட்ட பதிவைப் பயன்படுத்தவும்
உங்கள் தேவைகளின் அடிப்படையில் Winston, Pino, அல்லது Bunyan போன்ற பொருத்தமான பதிவு நூலகங்களைத் தேர்ந்தெடுக்கவும்
சிறந்த நடைமுறைகளைப் பயன்படுத்தவும்: சரியான பதிவு நிலைகளைப் பயன்படுத்தவும், சூழலைச் சேர்க்கவும் மற்றும் உணர்திறன் தரவைப் பாதுகாக்கவும்
உற்பத்தி சூழல்களுக்கு பதிவு சுழற்சி மற்றும் மையப்படுத்தப்பட்ட பதிவைச் செயல்படுத்தவும்
உங்கள் பதிவு உத்தியை வடிவமைக்கும் போது செயல்திறன் மற்றும் பாதுகாப்பு தாக்கங்களைக் கருத்தில் கொள்ளவும்
விநியோகிக்கப்பட்ட அமைப்புகளில் கோரிக்கைகளைக் கண்காணிக்க தொடர்பு IDகளைப் பயன்படுத்தவும்

பயிற்சி

சரியான சொல்லை தேர்வு செய்யவும்.

Logging ______ allows you to categorize messages by importance.

formats
✗ தவறு! "formats" என்பது பதிவு செய்திகளின் கட்டமைப்பைக் குறிக்கிறது, முக்கியத்துவத்தை அல்ல
transports
✗ தவறு! "transports" என்பது பதிவுகள் எங்கு அனுப்பப்படுகின்றன என்பதைக் குறிக்கிறது
levels
✓ சரி! "Logging levels" என்பது செய்திகளை முக்கியத்துவத்தின் அடிப்படையில் வகைப்படுத்த உங்களை அனுமதிக்கிறது
contexts
✗ தவறு! "contexts" என்பது கூடுதல் தகவலைச் சேர்க்கிறது, ஆனால் முக்கியத்துவத்தால் வகைப்படுத்தாது